<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>智能分镜</title>
    <style>
      /* 遮罩层 */
      .overlay {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        z-index: 1;
      }

      /* 弹窗样式 */
      .modal {
        display: none;
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background: #fff;
        padding: 20px;
        box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
        z-index: 2;
        width: 300px;
        text-align: center;
        border-radius: 10px;
      }

      /* 关闭按钮 */
      .close-btn {
        background-color: #f44336;
        color: white;
        border: none;
        padding: 5px 10px;
        cursor: pointer;
        border-radius: 5px;
        margin-top: 10px;
      }

      .close-btn:hover {
        background-color: #d32f2f;
      }

      table {
        border-collapse: collapse;
        /* 合并边框 */
        border: none;
        /* 隐藏表格边框 */
      }

      th,
      td {
        border: none;
        /* 隐藏单元格边框 */
        padding: 10px;
        /* 添加一些内边距 */
      }

      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      .container {
        padding: 20px;
      }

      .btn-primary {
        padding: 8px 16px;
        background-color: #5048e5;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }

      .input-group {
        display: flex;
        align-items: center;
        gap: 12px;
      }

      .input-group label {
        font-size: 20px;
        color: #666;
        white-space: nowrap;
      }

      .input-group .long-input {
        flex: 1;
        height: 40px;
        padding: 8px 12px;
        border: 1px solid #ddd;
        border-radius: 4px;
        font-size: 20px;
      }

      .button-group {
        display: flex;
        gap: 10px;
        align-items: center;
        justify-content: space-between;
        margin: 20px 0;
        width: 20%;
      }

      .open-file-btn {
        display: inline-block;
        background: #1890ff;
        color: white;
        padding: 8px 16px;
        border-radius: 4px;
        text-decoration: none;
        margin: 10px;
      }

      .input-group {
        display: flex;
        align-items: center;
        margin-bottom: 15px;
        gap: 10px;
      }

      .input-group label {
        min-width: 80px;
        color: #666;
      }

      .input-group input[type="text"] {
        flex: 1;
        padding: 8px;
        border: 1px solid #ddd;
        border-radius: 4px;
      }

      .button-group {
        display: flex;
        gap: 10px;
        margin-bottom: 20px;
      }

      .btn {
        padding: 8px 16px;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }

      .file-list {
        margin: 20px 0;
        border: 1px solid #ddd;
        border-radius: 4px;
      }

      .file-list table {
        width: 100%;
        border-collapse: collapse;
      }

      .file-list th,
      .file-list td {
        padding: 12px;
        text-align: left;
        border-bottom: 1px solid #ddd;
      }

      .file-list th {
        background-color: #f8f9fa;
        font-weight: normal;
        color: #666;
      }

      .options-group {
        margin: 20px 0;
      }

      .slider-group {
        display: flex;
        align-items: center;
        gap: 10px;
      }

      .slider {
        flex: 1;
        height: 4px;
        background: #ddd;
        border-radius: 2px;
      }

      input[type="checkbox"] {
        cursor: pointer;
      }

      .radio-group {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 10px;
      }

      .radio-group {
        display: flex;
        align-items: center;
        gap: 10px;
      }

      .input-group select.long-input {
        appearance: none;
        background: #fff
          url('data:image/svg+xml;charset=US-ASCII, <svg width="12" height="12" xmlns="http://www.w3.org/2000/svg"><path d="M6 9L1 4h10z" fill="%23999" /></svg>')
          no-repeat right 12px center;
        padding-right: 30px;
      }

      .input {
        padding: 5px;
      }

      /* 隐藏原生复选框 */
      .custom-checkbox input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
        height: 0;
        width: 0;
      }

      /* 自定义复选框外观 */
      .custom-checkbox .checkmark {
        position: relative;
        display: inline-block;
        width: 18px;
        height: 18px;
        background-color: #fff;
        border: 2px solid #ccc;
        border-radius: 3px;
        margin-right: 8px;
        vertical-align: middle;
        top: -3px;
      }

      /* 选中状态样式 */
      .custom-checkbox input:checked ~ .checkmark {
        background-color: #5048e5;
        border-color: #5048e5;
      }

      /* 勾选图标（使用伪元素） */
      .custom-checkbox .checkmark:after {
        content: "";
        position: absolute;
        display: none;
        left: 3px;
        top: -1px;
        width: 5px;
        height: 10px;
        border: solid white;
        border-width: 0 2px 2px 0;
        transform: rotate(45deg);
      }

      .custom-checkbox input:checked ~ .checkmark:after {
        display: block;
      }

      /* 隐藏原生单选框 */
      .custom-radio input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
      }

      .custom-radio {
        margin-right: 10px;
      }

      /* 自定义单选框外观 */
      .custom-radio .radio-icon {
        position: relative;
        display: inline-block;
        width: 18px;
        height: 18px;
        border: 2px solid #999;
        border-radius: 50%;
        margin-right: 10px;
        vertical-align: middle;
        transition: all 0.3s ease;
        top: -3px;
      }

      /* 选中状态样式 */
      .custom-radio input:checked ~ .radio-icon {
        border-color: #5048e5;
        background-color: #5048e5;
        box-shadow: inset 0 0 0 3px white; /* 内圆效果 */
      }

      /* 悬浮交互效果 */
      .custom-radio:hover .radio-icon {
        border-color: #555;
      }

      /* 禁用状态 */
      .custom-radio input:disabled ~ .radio-icon {
        background-color: #eee;
        border-color: #ccc;
      }

      .range-container {
        --track-height: 4px;
        --thumb-size: 18px;
        --primary-color: #5048e5;
        --track-fill: linear-gradient(
          90deg,
          var(--primary-color) 0%,
          var(--primary-color) var(--fill-percent, 100%),
          #e3e3e3 var(--fill-percent, 100%),
          #e3e3e3 100%
        );
        position: relative;
        width: 10%;
        padding: 15px 0;
        top: -3px;
        margin-right: 10px;
      }

      .custom-range {
        -webkit-appearance: none;
        appearance: none;
        width: 100%;
        height: var(--track-height);
        background: var(--track-fill);
        border-radius: 10px;
        outline: none;
        margin: 0;
        transition: background 0.3s ease;
      }

      /* Webkit/Blink 内核 */
      .custom-range::-webkit-slider-thumb {
        -webkit-appearance: none;
        width: var(--thumb-size);
        height: var(--thumb-size);
        background: white;
        border: 2px solid var(--primary-color);
        border-radius: 50%;
        cursor: pointer;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
        transition: transform 0.2s, box-shadow 0.2s;
      }

      /* Firefox 内核 */
      .custom-range::-moz-range-thumb {
        width: var(--thumb-size);
        height: var(--thumb-size);
        background: white;
        border: 2px solid var(--primary-color);
        border-radius: 50%;
        cursor: pointer;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
      }

      .number-input-container {
        --primary-color: hsl(210, 90%, 55%);
        --border-color: #ddd;
        --focus-glow: 0 0 0 3px rgba(33, 150, 243, 0.2);
        display: inline-flex;
        align-items: center;
        position: relative;
      }

      .custom-number-input {
        -webkit-appearance: none;
        appearance: none;
        width: 80px;
        padding: 8px 12px;
        border: 1px solid var(--border-color);
        border-radius: 6px;
        font-size: 14px;
        line-height: 1.5;
        transition: border-color 0.3s, box-shadow 0.3s;
      }

      /* Firefox 移除箭头 */
      .custom-number-input[type="number"] {
        -moz-appearance: textfield;
      }

      .custom-select {
        /* 基础样式 */
        padding: 8px 12px;
        border: 1px solid #ccc;
        border-radius: 4px;
        background-color: white;
        font-size: 14px;
        color: #333;
        cursor: pointer;

        /* 移除默认箭头（可选） */
        appearance: none;
        -webkit-appearance: none;
        -moz-appearance: none;

        /* 添加自定义箭头图标 */
        background-image: url('data:image/svg+xml;utf8,<svg fill="%23333" height="16" viewBox="0 0 24 24" width="16" xmlns="http://www.w3.org/2000/svg"><path  d="M7 10l5 5 5-5z"/></svg>');
        background-repeat: no-repeat;
        background-position: right 10px center;
      }

      /* 悬停和焦点状态 */
      .custom-select:hover {
        border-color: #888;
      }
      .custom-select:focus {
        outline: none;
        border-color: #0066ff;
        box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.2);
      }
    </style>
    <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
  </head>
  <body>
    <div class="container">
      <div id="overlay" class="overlay" onclick="closeModal()"></div>

      <div id="modal" class="modal">
        <p id="message">消息弹窗</p>
        <!-- TODO: 调整消息弹窗样式 -->
        <button class="close-btn" onclick="closeModal()">关闭</button>
      </div>

      <!-- Left Panel -->
      <div class="left-panel">
        <div class="input-group">
          <label>素材目录:</label>
          <label for="clipInput"></label
          ><input
            type="text"
            id="clipInput"
            placeholder="请选择视频文件/文件夹"
            onclick="clipInput('clipInput')"
            value=""
          />
          <span id="clipInputCount">视频数量: 0</span>
        </div>
        <div class="input-group">
          <label>导出目录:</label>
          <label for="clipOutput"></label
          ><input
            type="text"
            onclick="chooseFolder('clipOutput')"
            id="clipOutput"
            placeholder="请选择文件夹"
            value=""
          />
        </div>

        <div class="button-group">
          <button
            class="btn btn-primary"
            id="open-file-btn"
            onclick="openFile('clipOutput')"
          >
            打开文件夹
          </button>
          <button class="btn btn-primary" onclick="start_clip()">
            开始分镜任务
          </button>
          <button
            class="btn btn-primary"
            id="stop-split"
            onclick="stop_worker()"
          >
            停止任务
          </button>
        </div>
        <div class="status-bar">
          已选择<span class="red-text" id="select_video_count_total">0</span
          >个视频 总时长: <span id="select_video_duration_total">0.00</span>分钟
          <label class="custom-checkbox">
            <input type="checkbox" id="selectAll" onchange="selectAll()" />
            <span class="checkmark"></span>
            <label for="selectAll">选择全部</label>
          </label>
          <div class="file-list">
            <table>
              <thead>
                <tr>
                  <td>选择</td>
                  <th>序号</th>
                  <th>文件名</th>
                  <th>时长</th>
                  <th>大小</th>
                </tr>
              </thead>
              <tbody id="shotListBody">
                <!-- 动态生成的行将被插入这里 -->
              </tbody>
            </table>
          </div>
        </div>

        <div class="options-group">
          <label>分镜模式:</label>
          <div class="radio-group" id="split-mode-group">
            <label class="custom-radio">
              <input type="radio" name="split_mode" value="scene" checked />
              <span class="radio-icon"></span>
              <label>按场景智能分镜</label>
            </label>
            <label class="custom-radio">
              <input type="radio" name="split_mode" value="duration" />
              <span class="radio-icon"></span>
              <label>按固定分镜时长分镜</label>
            </label>
            <label class="custom-radio">
              <input type="radio" name="split_mode" value="count" />
              <span class="radio-icon"></span>
              <label>按分镜数量分镜</label>
            </label>
            <label class="custom-radio">
              <input type="radio" name="split_mode" value="voice" />
              <span class="radio-icon"></span>
              <label>按口播分镜</label>
            </label>
            <label class="custom-radio">
              <input type="radio" name="split_mode" value="emotion" />
              <span class="radio-icon"></span>
              <label>AI精准转场分镜</label>
            </label>
          </div>
        </div>

        <div class="options-group">
          <label>参数设置:</label>
          <div id="param-setting"></div>
        </div>
        <div class="options-group">
          <label>文件输出:</label>
          <div class="radio-group">
            <label class="custom-radio">
              <input type="radio" name="split_save_mode" value="true" checked />
              <span class="radio-icon"></span>
              <label>分目录保存</label>
            </label>
            <label class="custom-radio">
              <input type="radio" name="split_save_mode" value="false" />
              <span class="radio-icon"></span>
              <label>同目录保存</label>
            </label>
          </div>
        </div>
      </div>
    </div>

    <script type="text/javascript">
      document.addEventListener("DOMContentLoaded", function () {
        let item = {
          paramRange: 0.5,
          durationInput: 5,
          countInput: 5,
          normal: {},
          advanced: {},
          pro: {},
          auto: {},
        };
        let items = [];

        new QWebChannel(parent.qt.webChannelTransport, function (channel) {
          Bridge = channel.objects.Bridge;

          Bridge.started.connect(function (msg) {
            showModal(msg);
          });
          Bridge.finished.connect(function (msg) {
            showModal(msg);
          });
          Bridge.failed.connect(function (msg) {
            showModal(msg);
          });

          /*  文件操作方法  */
          // 选择文件夹
          window.chooseFolder = function (eid) {
            Bridge.choose_folder(eid);
          };

          // 打开文件或者文件夹
          window.openFile = function (eid) {
            let path = document.getElementById(eid).value;
            if (path) {
              Bridge.open_file(path);
            }
          };

          // 选择的文件夹信号槽
          Bridge.select_folder_result.connect(function (eid, path) {
            document.getElementById(eid).value = path;
          });
          // 返回智能分镜目录
          Bridge.select_files_result.connect(function (eid, files, count) {
            // 渲染基础合成分镜列表
            const tbody = document.getElementById("shotListBody");
            if (!tbody) {
              return;
            }
            let files_list = [];
            items = [];
            for (let file_item of files) {
              files_list.push(`
                        <tr data-id="">
                            <td>
                             <label class="custom-checkbox">
                              <input type="checkbox" class="row-check" value="${file_item.file}">
                                <span class="checkmark"></span>                
                             </label>                                   
                            </td>
                            <td>${file_item.id}</td>
                            <td>${file_item.file}</td>
                            <td>${file_item.duration}秒</td>
                            <td>${file_item.size}</td>
                        </tr>
                    `);
              file_item.status = false;
              items.push(file_item);
            }
            tbody.innerHTML = files_list.join("");
            // 更新选择的文件数量
            document.getElementById("clipInputCount").innerText =
              "视频数量: " + count;
            bindEventListeners();
          });
          window.clipInput = function () {
            Bridge.choose_folder_and_read_video_files("clipInput");
          };

          /*  操作逻辑  */
          // 开始分镜
          window.start_clip = function () {
            const table = document.getElementById("shotListBody");
            const rows = table.querySelectorAll("tbody tr");
            const selectedValues = [];

            rows.forEach((row) => {
              const checkbox = row.querySelector(
                "td:nth-child(1) input[type='checkbox']"
              );
              if (checkbox && checkbox.checked) {
                selectedValues.push(checkbox.value);
              }
            });
            if (selectedValues.length === 0) {
              showModal("请选择分镜");
              return;
            }

            let output_path = document.getElementById("clipOutput").value,
              selected = document.querySelector(
                'input[name="split_mode"]:checked'
              ).value;
            if (!output_path) {
              showModal("请选择输出目录");
              return;
            }
            let task_items = {
              task: "视频分镜",
              channel: selected,
              input_files: selectedValues,
              output_folder: output_path,
              arg: null,
            };
            if (selected === "scene") {
              task_items.arg = item.paramRange;
            } else if (selected === "duration") {
              task_items.arg = item.durationInput;
            } else if (selected === "count") {
              task_items.arg = item.countInput;
            }
            Bridge.start_worker(JSON.stringify(task_items));
          };

          // 停止生成
          window.stop_worker = function () {
            Bridge.stop();
          };
        });
        // 开始任务
        let selected_video_count_elm = document.getElementById(
            "select_video_count_total"
          ),
          selected_video_duration_elm = document.getElementById(
            "select_video_duration_total"
          );

        window.showModal = function (message) {
          document.getElementById("message").innerText = message;
          document.getElementById("overlay").style.display = "block";
          document.getElementById("modal").style.display = "block";
        };

        window.closeModal = function () {
          document.getElementById("overlay").style.display = "none";
          document.getElementById("modal").style.display = "none";
        };

        // 选择全部
        window.selectAll = function () {
          let selectAllCheckbox = document.getElementById("selectAll");
          let rowCheckboxes = document.querySelectorAll(".row-check");
          rowCheckboxes.forEach((checkbox) => {
            checkbox.checked = selectAllCheckbox.checked;
          });
          if (selectAllCheckbox.checked) {
            selected_video_count_elm.innerText = rowCheckboxes.length;
            // 从items中计算总时长
            let total_duration = 0;
            for (let item of items) {
              total_duration += item.duration;
              item.status = true;
            }
            selected_video_duration_elm.innerText = (
              total_duration / 60
            ).toFixed(2);
          } else {
            for (let item of items) {
              item.status = false;
            }
            selected_video_count_elm.innerText = 0;
            selected_video_duration_elm.innerText = 0;
          }
        };

        window.update_total = function () {
          let total_duration = 0;
          let total_count = 0;
          for (let item of items) {
            if (item.status) {
              total_duration += item.duration;
              total_count++;
            }
          }
          selected_video_count_elm.innerText = total_count;
          selected_video_duration_elm.innerText = (total_duration / 60).toFixed(
            2
          );
        };

        // 监听单个视频选择
        window.bindEventListeners = function () {
          document.querySelectorAll(".row-check").forEach((checkbox) => {
            checkbox.addEventListener("change", function (event) {
              if (checkbox.checked) {
                for (let item of items) {
                  if (item.file === event.target.value) {
                    item.status = true;
                  }
                }
              } else {
                for (let item of items) {
                  if (item.file === event.target.value) {
                    item.status = false;
                  }
                }
              }
              update_total();
            });
          });
        };

        window.renderParamSetting = function (mode) {
          const container = document.getElementById("param-setting");
          container.innerHTML = ""; // 清空之前的内容

          if (mode === "scene") {
            // 滑动条参数（0.2 ~ 0.9）
            const sliderDiv = document.createElement("div");
            sliderDiv.className = "slider-group";
            sliderDiv.innerHTML = `
                <div class="range-container">
                 <input 
                  type="range"
                  id="paramRange"
                  min="0.2"
                  max="0.9"
                  step="0.01"
                  value="${item.paramRange}" 
                  class="custom-range"
                >
                </div>
                <span id="paramValue">${item.paramRange}</span>
                            `;
            container.appendChild(sliderDiv);
            document
              .getElementById("paramRange")
              .addEventListener("input", function () {
                document.getElementById("paramValue").textContent = this.value;
                item.paramRange = this.value;
              });
          } else if (mode === "duration") {
            // 输入框，单位：秒
            container.innerHTML = `
                      <div class="number-input-container">
                        <input 
                          type="number"
                          id="durationInput"
                          step="1"
                          min="1"
                          value="${item.durationInput}" 
                          class="custom-number-input"
                        >
                        <span class="unit-label">秒</span>
                      </div>
                            `;
            document
              .getElementById("durationInput")
              .addEventListener("input", function () {
                item.durationInput = this.value;
              });
          } else if (mode === "count") {
            // 输入框，单位：个分镜
            container.innerHTML = `
                      <div class="number-input-container">
                        <input 
                          type="number"
                          id="countInput"
                          step="1"
                          min="1"
                          value="${item.countInput}" 
                          class="custom-number-input"
                        >
                        <span class="unit-label">个分镜</span>
                      </div>
                            `;
            document
              .getElementById("countInput")
              .addEventListener("input", function () {
                item.countInput = this.value;
              });
          } else {
            container.innerHTML = `<span style="color: #888;">该模式不需要参数设置</span>`;
          }
        };
        renderParamSetting("scene");
        // 监听单选框变化
        document
          .querySelectorAll('input[name="split_mode"]')
          .forEach((radio) => {
            radio.addEventListener("change", function () {
              renderParamSetting(this.value);
            });
          });
      });
    </script>
  </body>
</html>
